home *** CD-ROM | disk | FTP | other *** search
- /* texture.c */
-
- /*
- * Mesa 3-D graphics library
- * Version: 1.2
- * Copyright (C) 1995 Brian Paul (brianp@ssec.wisc.edu)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- $Id: texture.c,v 1.22 1995/11/22 13:38:01 brianp Exp $
-
- $Log: texture.c,v $
- * Revision 1.22 1995/11/22 13:38:01 brianp
- * removed texcoord clamping optimization
- *
- * Revision 1.21 1995/11/13 21:45:53 brianp
- * fixed bug in texture border logic
- * added F suffix to many constants
- *
- * Revision 1.20 1995/11/09 16:57:52 brianp
- * fixed bugs in apply_texture for GL_BLEND per Johan Nouvel
- *
- * Revision 1.19 1995/11/03 17:39:30 brianp
- * removed unused variable, added casts for C++ compilation
- *
- * Revision 1.18 1995/10/14 17:42:45 brianp
- * compile glTexEnv, glTexParameter, and glTexGen into display lists
- *
- * Revision 1.17 1995/08/31 21:28:59 brianp
- * new TexGenEnabled bitfield
- * fixed a bug in spherical normal generation
- *
- * Revision 1.16 1995/07/24 20:35:40 brianp
- * replaced memset() with MEMSET() and memcpy() with MEMCPY()
- *
- * Revision 1.15 1995/07/20 15:36:06 brianp
- * added casts to PROD macro to suppress warnings with Sun's cc
- *
- * Revision 1.14 1995/06/12 15:43:06 brianp
- * changed color arrays to GLubyte
- *
- * Revision 1.13 1995/05/30 15:41:23 brianp
- * fixed GL_LUMINANCE bug in unpack_texture()
- *
- * Revision 1.12 1995/05/30 15:11:13 brianp
- * added more error checking to glGetTexLevelParamater[fi]v()
- * added glGetTexImage() stub
- *
- * Revision 1.11 1995/05/29 21:23:38 brianp
- * added glGetTexEnv*(), glGetTexGen*(), glGetTex[Level]Parameter*() functions
- *
- * Revision 1.10 1995/05/22 21:02:41 brianp
- * Release 1.2
- *
- * Revision 1.9 1995/05/18 14:46:51 brianp
- * fixed texture DeleteFlag bug
- *
- * Revision 1.8 1995/05/16 14:09:44 brianp
- * more data types supported by glTexImage1/2D()
- *
- * Revision 1.7 1995/05/15 16:09:41 brianp
- * store textures as GLubytes instead of GLfloats
- * implemented GL_MODULATE, GL_DECAL, GL_BLEND and GL_REPLACE_EXT modes
- * save 1D and 2D textures in display lists
- *
- * Revision 1.6 1995/03/17 20:14:50 brianp
- * small bug fixes
- *
- * Revision 1.5 1995/03/10 15:19:23 brianp
- * added divide by zero check to gl_texgen
- *
- * Revision 1.4 1995/03/09 21:33:12 brianp
- * removed #include stdio.h
- *
- * Revision 1.3 1995/03/04 19:29:44 brianp
- * 1.1 beta revision
- *
- * Revision 1.2 1995/03/02 19:11:30 brianp
- * modified gl_texgen and gl_texture_span_1d
- *
- * Revision 1.1 1995/02/24 14:28:31 brianp
- * Initial revision
- *
- */
-
-
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "context.h"
- #include "list.h"
- #include "macros.h"
- #include "pb.h"
-
-
- #ifndef NULL
- # define NULL 0
- #endif
-
-
-
- /**********************************************************************/
- /* Texture Environment */
- /**********************************************************************/
-
-
-
- void gl_texenv( GLenum target, GLenum pname, const GLfloat *param )
- {
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glTexEnv" );
- return;
- }
-
- if (target!=GL_TEXTURE_ENV) {
- gl_error( GL_INVALID_ENUM, "glTexEnv(target)" );
- return;
- }
-
- if (pname==GL_TEXTURE_ENV_MODE) {
- GLenum mode = (GLenum) (GLint) *param;
- switch (mode) {
- case GL_MODULATE:
- case GL_BLEND:
- case GL_DECAL:
- case GL_REPLACE_EXT:
- CC.Texture.EnvMode = mode;
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glTexEnv(param)" );
- return;
- }
- }
- else if (pname==GL_TEXTURE_ENV_COLOR) {
- CC.Texture.EnvColor[0] = CLAMP( param[0], 0.0, 1.0 );
- CC.Texture.EnvColor[1] = CLAMP( param[1], 0.0, 1.0 );
- CC.Texture.EnvColor[2] = CLAMP( param[2], 0.0, 1.0 );
- CC.Texture.EnvColor[3] = CLAMP( param[3], 0.0, 1.0 );
- }
- else {
- gl_error( GL_INVALID_ENUM, "glTexEnv(pname)" );
- return;
- }
- }
-
-
-
- void glTexEnvf( GLenum target, GLenum pname, GLfloat param )
- {
- if (CC.CompileFlag) {
- gl_save_texenv( target, pname, ¶m );
- }
- if (CC.ExecuteFlag) {
- gl_texenv( target, pname, ¶m );
- }
- }
-
-
-
- void glTexEnvi( GLenum target, GLenum pname, GLint param )
- {
- GLfloat p = (GLfloat) param;
- if (CC.CompileFlag) {
- gl_save_texenv( target, pname, &p );
- }
- if (CC.ExecuteFlag) {
- gl_texenv( target, pname, &p );
- }
- }
-
-
-
- void glTexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
- {
- if (CC.CompileFlag) {
- gl_save_texenv( target, pname, param );
- }
- if (CC.ExecuteFlag) {
- gl_texenv( target, pname, param );
- }
- }
-
-
-
- void glTexEnviv( GLenum target, GLenum pname, const GLint *param )
- {
- GLfloat p[4];
- p[0] = INT_TO_FLOAT( param[0] );
- p[1] = INT_TO_FLOAT( param[1] );
- p[2] = INT_TO_FLOAT( param[2] );
- p[3] = INT_TO_FLOAT( param[3] );
- if (CC.CompileFlag) {
- gl_save_texenv( target, pname, p );
- }
- if (CC.ExecuteFlag) {
- gl_texenv( target, pname, p );
- }
- }
-
-
-
-
- void glGetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
- {
- if (target!=GL_TEXTURE_ENV) {
- gl_error( GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
- return;
- }
- switch (pname) {
- case GL_TEXTURE_ENV_MODE:
- *params = (GLfloat) CC.Texture.EnvMode;
- break;
- case GL_TEXTURE_ENV_COLOR:
- COPY_4V( params, CC.Texture.EnvColor );
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
- }
- }
-
-
- void glGetTexEnviv( GLenum target, GLenum pname, GLint *params )
- {
- if (target!=GL_TEXTURE_ENV) {
- gl_error( GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
- return;
- }
- switch (pname) {
- case GL_TEXTURE_ENV_MODE:
- *params = (GLint) CC.Texture.EnvMode;
- break;
- case GL_TEXTURE_ENV_COLOR:
- params[0] = FLOAT_TO_INT( CC.Texture.EnvColor[0] );
- params[1] = FLOAT_TO_INT( CC.Texture.EnvColor[1] );
- params[2] = FLOAT_TO_INT( CC.Texture.EnvColor[2] );
- params[3] = FLOAT_TO_INT( CC.Texture.EnvColor[3] );
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
- }
- }
-
-
-
-
- /**********************************************************************/
- /* Texture Parameters */
- /**********************************************************************/
-
-
- void gl_texparameter( GLenum target, GLenum pname, const GLfloat *params )
- {
- GLenum eparam = (GLenum) (GLint) params[0];
-
- if (target==GL_TEXTURE_1D) {
- switch (pname) {
- case GL_TEXTURE_MIN_FILTER:
- if (eparam==GL_NEAREST || eparam==GL_LINEAR
- || eparam==GL_NEAREST_MIPMAP_NEAREST
- || eparam==GL_LINEAR_MIPMAP_NEAREST
- || eparam==GL_NEAREST_MIPMAP_LINEAR
- || eparam==GL_LINEAR_MIPMAP_LINEAR) {
- CC.Texture.MinFilter1D = eparam;
- }
- else {
- gl_error( GL_INVALID_VALUE, "glTexParameter(param)" );
- }
- break;
- case GL_TEXTURE_MAG_FILTER:
- if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
- CC.Texture.MagFilter1D = eparam;
- }
- else {
- gl_error( GL_INVALID_VALUE, "glTexParameter(param)" );
- }
- break;
- case GL_TEXTURE_WRAP_S:
- if (eparam==GL_CLAMP || eparam==GL_REPEAT) {
- CC.Texture.WrapS1D = eparam;
- }
- else {
- gl_error( GL_INVALID_VALUE, "glTexParameter(param)" );
- }
- break;
- case GL_TEXTURE_WRAP_T:
- if (eparam==GL_CLAMP || eparam==GL_REPEAT) {
- CC.Texture.WrapT1D = eparam;
- }
- else {
- gl_error( GL_INVALID_VALUE, "glTexParameter(param)" );
- }
- break;
- case GL_TEXTURE_BORDER_COLOR:
- CC.Texture.BorderColor[0] = CLAMP( params[0], 0.0, 1.0 );
- CC.Texture.BorderColor[1] = CLAMP( params[1], 0.0, 1.0 );
- CC.Texture.BorderColor[2] = CLAMP( params[2], 0.0, 1.0 );
- CC.Texture.BorderColor[3] = CLAMP( params[3], 0.0, 1.0 );
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glTexParameter(pname)" );
- }
- }
- else if (target==GL_TEXTURE_2D) {
- switch (pname) {
- case GL_TEXTURE_MIN_FILTER:
- if (eparam==GL_NEAREST || eparam==GL_LINEAR
- || eparam==GL_NEAREST_MIPMAP_NEAREST
- || eparam==GL_LINEAR_MIPMAP_NEAREST
- || eparam==GL_NEAREST_MIPMAP_LINEAR
- || eparam==GL_LINEAR_MIPMAP_LINEAR) {
- CC.Texture.MinFilter2D = eparam;
- }
- else {
- gl_error( GL_INVALID_VALUE, "glTexParameter(param)" );
- }
- break;
- case GL_TEXTURE_MAG_FILTER:
- if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
- CC.Texture.MagFilter2D = eparam;
- }
- else {
- gl_error( GL_INVALID_VALUE, "glTexParameter(param)" );
- }
- break;
- case GL_TEXTURE_WRAP_S:
- if (eparam==GL_CLAMP || eparam==GL_REPEAT) {
- CC.Texture.WrapS2D = eparam;
- }
- else {
- gl_error( GL_INVALID_VALUE, "glTexParameter(param)" );
- }
- break;
- case GL_TEXTURE_WRAP_T:
- if (eparam==GL_CLAMP || eparam==GL_REPEAT) {
- CC.Texture.WrapT2D = eparam;
- }
- else {
- gl_error( GL_INVALID_VALUE, "glTexParameter(param)" );
- }
- break;
- case GL_TEXTURE_BORDER_COLOR:
- CC.Texture.BorderColor[0] = CLAMP( params[0], 0.0, 1.0 );
- CC.Texture.BorderColor[1] = CLAMP( params[1], 0.0, 1.0 );
- CC.Texture.BorderColor[2] = CLAMP( params[2], 0.0, 1.0 );
- CC.Texture.BorderColor[3] = CLAMP( params[3], 0.0, 1.0 );
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glTexParameter(pname)" );
- }
- }
- else {
- gl_error( GL_INVALID_ENUM, "glTexParameter(target)" );
- }
- }
-
-
-
- void glTexParameterf( GLenum target, GLenum pname, GLfloat param )
- {
- if (CC.CompileFlag) {
- gl_save_texparameter( target, pname, ¶m );
- }
- if (CC.ExecuteFlag) {
- gl_texparameter( target, pname, ¶m );
- }
- }
-
-
-
- void glTexParameteri( GLenum target, GLenum pname, GLint param )
- {
- GLfloat fparam = param;
- if (CC.CompileFlag) {
- gl_save_texparameter( target, pname, &fparam );
- }
- if (CC.ExecuteFlag) {
- gl_texparameter( target, pname, &fparam );
- }
- }
-
-
-
- void glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
- {
- if (CC.CompileFlag) {
- gl_save_texparameter( target, pname, params );
- }
- if (CC.ExecuteFlag) {
- gl_texparameter( target, pname, params );
- }
- }
-
-
-
- void glTexParameteriv( GLenum target, GLenum pname, const GLint *params )
- {
- GLfloat p[4];
- if (pname==GL_TEXTURE_BORDER_COLOR) {
- p[0] = INT_TO_FLOAT( params[0] );
- p[1] = INT_TO_FLOAT( params[1] );
- p[2] = INT_TO_FLOAT( params[2] );
- p[3] = INT_TO_FLOAT( params[3] );
- }
- else {
- p[0] = (GLfloat) params[0];
- p[1] = (GLfloat) params[1];
- p[2] = (GLfloat) params[2];
- p[3] = (GLfloat) params[3];
- }
- if (CC.CompileFlag) {
- gl_save_texparameter( target, pname, p );
- }
- if (CC.ExecuteFlag) {
- gl_texparameter( target, pname, p );
- }
- }
-
-
- void glGetTexLevelParameterfv( GLenum target, GLint level,
- GLenum pname, GLfloat *params )
- {
- if (level<0 || level>=MAX_TEXTURE_LEVELS) {
- gl_error( GL_INVALID_VALUE, "glGetTexLevelParameterfv" );
- return;
- }
-
- switch (target) {
- case GL_TEXTURE_1D:
- switch (pname) {
- case GL_TEXTURE_WIDTH:
- *params = (GLfloat) CC.TextureWidth1D[level];
- break;
- case GL_TEXTURE_COMPONENTS:
- *params = (GLfloat) CC.TextureComponents1D[level];
- break;
- case GL_TEXTURE_BORDER:
- *params = (GLfloat) CC.TextureBorder1D[level];
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexLevelParameterfv(pname)" );
- }
- break;
- case GL_TEXTURE_2D:
- switch (pname) {
- case GL_TEXTURE_WIDTH:
- *params = (GLfloat) CC.TextureWidth2D[level];
- break;
- case GL_TEXTURE_HEIGHT:
- *params = (GLfloat) CC.TextureHeight2D[level];
- break;
- case GL_TEXTURE_COMPONENTS:
- *params = (GLfloat) CC.TextureComponents2D[level];
- break;
- case GL_TEXTURE_BORDER:
- *params = (GLfloat) CC.TextureBorder2D[level];
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexLevelParameterfv(pname)" );
- }
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexLevelParameterfv(target)" );
- }
- }
-
-
- void glGetTexLevelParameteriv( GLenum target, GLint level,
- GLenum pname, GLint *params )
- {
- if (level<0 || level>=MAX_TEXTURE_LEVELS) {
- gl_error( GL_INVALID_VALUE, "glGetTexLevelParameteriv" );
- return;
- }
-
- switch (target) {
- case GL_TEXTURE_1D:
- switch (pname) {
- case GL_TEXTURE_WIDTH:
- *params = CC.TextureWidth1D[level];
- break;
- case GL_TEXTURE_COMPONENTS:
- *params = CC.TextureComponents1D[level];
- break;
- case GL_TEXTURE_BORDER:
- *params = CC.TextureBorder1D[level];
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexLevelParameteriv(pname)" );
- }
- break;
- case GL_TEXTURE_2D:
- switch (pname) {
- case GL_TEXTURE_WIDTH:
- *params = CC.TextureWidth2D[level];
- break;
- case GL_TEXTURE_HEIGHT:
- *params = CC.TextureHeight2D[level];
- break;
- case GL_TEXTURE_COMPONENTS:
- *params = CC.TextureComponents2D[level];
- break;
- case GL_TEXTURE_BORDER:
- *params = CC.TextureBorder2D[level];
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexLevelParameteriv(pname)" );
- }
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexLevelParameteriv(target)" );
- }
- }
-
-
-
- void glGetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
- {
- switch (target) {
- case GL_TEXTURE_1D:
- switch (pname) {
- case GL_TEXTURE_MAG_FILTER:
- *params = (GLfloat) CC.Texture.MagFilter1D;
- break;
- case GL_TEXTURE_MIN_FILTER:
- *params = (GLfloat) CC.Texture.MinFilter1D;
- break;
- case GL_TEXTURE_WRAP_S:
- *params = (GLfloat) CC.Texture.WrapS1D;
- break;
- case GL_TEXTURE_WRAP_T:
- *params = (GLfloat) CC.Texture.WrapT1D;
- break;
- case GL_TEXTURE_BORDER_COLOR:
- COPY_4V( params, CC.Texture.BorderColor );
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
- }
- break;
- case GL_TEXTURE_2D:
- switch (pname) {
- case GL_TEXTURE_MAG_FILTER:
- *params = (GLfloat) CC.Texture.MagFilter2D;
- break;
- case GL_TEXTURE_MIN_FILTER:
- *params = (GLfloat) CC.Texture.MinFilter2D;
- break;
- case GL_TEXTURE_WRAP_S:
- *params = (GLfloat) CC.Texture.WrapS2D;
- break;
- case GL_TEXTURE_WRAP_T:
- *params = (GLfloat) CC.Texture.WrapT2D;
- break;
- case GL_TEXTURE_BORDER_COLOR:
- COPY_4V( params, CC.Texture.BorderColor );
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
- }
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexParameterfv(target)" );
- }
- }
-
-
- void glGetTexParameteriv( GLenum target, GLenum pname, GLint *params )
- {
- switch (target) {
- case GL_TEXTURE_1D:
- switch (pname) {
- case GL_TEXTURE_MAG_FILTER:
- *params = (GLint) CC.Texture.MagFilter1D;
- break;
- case GL_TEXTURE_MIN_FILTER:
- *params = (GLint) CC.Texture.MinFilter1D;
- break;
- case GL_TEXTURE_WRAP_S:
- *params = (GLint) CC.Texture.WrapS1D;
- break;
- case GL_TEXTURE_WRAP_T:
- *params = (GLint) CC.Texture.WrapT1D;
- break;
- case GL_TEXTURE_BORDER_COLOR:
- params[0] = FLOAT_TO_INT( CC.Texture.BorderColor[0] );
- params[1] = FLOAT_TO_INT( CC.Texture.BorderColor[1] );
- params[2] = FLOAT_TO_INT( CC.Texture.BorderColor[2] );
- params[3] = FLOAT_TO_INT( CC.Texture.BorderColor[3] );
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
- }
- break;
- case GL_TEXTURE_2D:
- switch (pname) {
- case GL_TEXTURE_MAG_FILTER:
- *params = (GLint) CC.Texture.MagFilter2D;
- break;
- case GL_TEXTURE_MIN_FILTER:
- *params = (GLint) CC.Texture.MinFilter2D;
- break;
- case GL_TEXTURE_WRAP_S:
- *params = (GLint) CC.Texture.WrapS2D;
- break;
- case GL_TEXTURE_WRAP_T:
- *params = (GLint) CC.Texture.WrapT2D;
- break;
- case GL_TEXTURE_BORDER_COLOR:
- params[0] = FLOAT_TO_INT( CC.Texture.BorderColor[0] );
- params[1] = FLOAT_TO_INT( CC.Texture.BorderColor[1] );
- params[2] = FLOAT_TO_INT( CC.Texture.BorderColor[2] );
- params[3] = FLOAT_TO_INT( CC.Texture.BorderColor[3] );
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
- }
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glGetTexParameteriv(target)" );
- }
- }
-
-
-
-
- /**********************************************************************/
- /* Texture Coord Generation */
- /**********************************************************************/
-
-
- void gl_texgen( GLenum coord, GLenum pname, const GLfloat *params )
- {
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glTexGenfv" );
- return;
- }
-
- switch( coord ) {
- case GL_S:
- if (pname==GL_TEXTURE_GEN_MODE) {
- GLenum mode = (GLenum) (GLint) *params;
- if (mode==GL_OBJECT_LINEAR ||
- mode==GL_EYE_LINEAR ||
- mode==GL_SPHERE_MAP) {
- CC.Texture.GenModeS = mode;
- }
- else {
- gl_error( GL_INVALID_ENUM, "glTexGenfv(param)" );
- return;
- }
- }
- else if (pname==GL_OBJECT_PLANE) {
- CC.Texture.ObjectPlaneS[0] = params[0];
- CC.Texture.ObjectPlaneS[1] = params[1];
- CC.Texture.ObjectPlaneS[2] = params[2];
- CC.Texture.ObjectPlaneS[3] = params[3];
- }
- else if (pname==GL_EYE_PLANE) {
- /* TODO: xform plane by modelview??? */
- CC.Texture.EyePlaneS[0] = params[0];
- CC.Texture.EyePlaneS[1] = params[1];
- CC.Texture.EyePlaneS[2] = params[2];
- CC.Texture.EyePlaneS[3] = params[3];
- }
- else {
- gl_error( GL_INVALID_ENUM, "glTexGenfv(pname)" );
- return;
- }
- break;
- case GL_T:
- if (pname==GL_TEXTURE_GEN_MODE) {
- GLenum mode = (GLenum) (GLint) *params;
- if (mode==GL_OBJECT_LINEAR ||
- mode==GL_EYE_LINEAR ||
- mode==GL_SPHERE_MAP) {
- CC.Texture.GenModeT = mode;
- }
- else {
- gl_error( GL_INVALID_ENUM, "glTexGenfv(param)" );
- return;
- }
- }
- else if (pname==GL_OBJECT_PLANE) {
- CC.Texture.ObjectPlaneT[0] = params[0];
- CC.Texture.ObjectPlaneT[1] = params[1];
- CC.Texture.ObjectPlaneT[2] = params[2];
- CC.Texture.ObjectPlaneT[3] = params[3];
- }
- else if (pname==GL_EYE_PLANE) {
- CC.Texture.EyePlaneT[0] = params[0];
- CC.Texture.EyePlaneT[1] = params[1];
- CC.Texture.EyePlaneT[2] = params[2];
- CC.Texture.EyePlaneT[3] = params[3];
- }
- else {
- gl_error( GL_INVALID_ENUM, "glTexGenfv(pname)" );
- return;
- }
- break;
- case GL_R:
- if (pname==GL_TEXTURE_GEN_MODE) {
- GLenum mode = (GLenum) (GLint) *params;
- if (mode==GL_OBJECT_LINEAR ||
- mode==GL_EYE_LINEAR) {
- CC.Texture.GenModeR = mode;
- }
- else {
- gl_error( GL_INVALID_ENUM, "glTexGenfv(param)" );
- return;
- }
- }
- else if (pname==GL_OBJECT_PLANE) {
- CC.Texture.ObjectPlaneR[0] = params[0];
- CC.Texture.ObjectPlaneR[1] = params[1];
- CC.Texture.ObjectPlaneR[2] = params[2];
- CC.Texture.ObjectPlaneR[3] = params[3];
- }
- else if (pname==GL_EYE_PLANE) {
- CC.Texture.EyePlaneR[0] = params[0];
- CC.Texture.EyePlaneR[1] = params[1];
- CC.Texture.EyePlaneR[2] = params[2];
- CC.Texture.EyePlaneR[3] = params[3];
- }
- else {
- gl_error( GL_INVALID_ENUM, "glTexGenfv(pname)" );
- return;
- }
- break;
- case GL_Q:
- if (pname==GL_TEXTURE_GEN_MODE) {
- GLenum mode = (GLenum) (GLint) *params;
- if (mode==GL_OBJECT_LINEAR ||
- mode==GL_EYE_LINEAR) {
- CC.Texture.GenModeQ = mode;
- }
- else {
- gl_error( GL_INVALID_ENUM, "glTexGenfv(param)" );
- return;
- }
- }
- else if (pname==GL_OBJECT_PLANE) {
- CC.Texture.ObjectPlaneQ[0] = params[0];
- CC.Texture.ObjectPlaneQ[1] = params[1];
- CC.Texture.ObjectPlaneQ[2] = params[2];
- CC.Texture.ObjectPlaneQ[3] = params[3];
- }
- else if (pname==GL_EYE_PLANE) {
- CC.Texture.EyePlaneQ[0] = params[0];
- CC.Texture.EyePlaneQ[1] = params[1];
- CC.Texture.EyePlaneQ[2] = params[2];
- CC.Texture.EyePlaneQ[3] = params[3];
- }
- else {
- gl_error( GL_INVALID_ENUM, "glTexGenfv(pname)" );
- return;
- }
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glTexGenfv(coord)" );
- return;
- }
-
- CC.NewState = GL_TRUE;
- }
-
-
-
- void glTexGend( GLenum coord, GLenum pname, GLdouble param )
- {
- GLfloat p = (GLfloat) param;
- if (CC.CompileFlag) {
- gl_save_texgen( coord, pname, &p );
- }
- if (CC.ExecuteFlag) {
- gl_texgen( coord, pname, &p );
- }
- }
-
-
- void glTexGenf( GLenum coord, GLenum pname, GLfloat param )
- {
- if (CC.CompileFlag) {
- gl_save_texgen( coord, pname, ¶m );
- }
- if (CC.ExecuteFlag) {
- gl_texgen( coord, pname, ¶m );
- }
- }
-
-
- void glTexGeni( GLenum coord, GLenum pname, GLint param )
- {
- GLfloat p = (GLfloat) param;
- if (CC.CompileFlag) {
- gl_save_texgen( coord, pname, &p );
- }
- if (CC.ExecuteFlag) {
- gl_texgen( coord, pname, &p );
- }
- }
-
-
- void glTexGendv( GLenum coord, GLenum pname, const GLdouble *params )
- {
- GLfloat p[4];
- p[0] = params[0];
- p[1] = params[1];
- p[2] = params[2];
- p[3] = params[3];
- if (CC.CompileFlag) {
- gl_save_texgen( coord, pname, p );
- }
- if (CC.ExecuteFlag) {
- gl_texgen( coord, pname, p );
- }
- }
-
-
- void glTexGeniv( GLenum coord, GLenum pname, const GLint *params )
- {
- GLfloat p[4];
- p[0] = params[0];
- p[1] = params[1];
- p[2] = params[2];
- p[3] = params[3];
- if (CC.CompileFlag) {
- gl_save_texgen( coord, pname, p );
- }
- if (CC.ExecuteFlag) {
- gl_texgen( coord, pname, p );
- }
- }
-
-
- void glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
- {
- if (CC.CompileFlag) {
- gl_save_texgen( coord, pname, params );
- }
- if (CC.ExecuteFlag) {
- gl_texgen( coord, pname, params );
- }
- }
-
-
- void glGetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
- {
- /* TODO */
- }
-
- void glGetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
- {
- /* TODO */
- }
-
- void glGetTexGeniv( GLenum coord, GLenum pname, GLint *params )
- {
- /* TODO */
- }
-
-
-
- /*
- * Perform automatic texture coordinate generation.
- * Input: obj - vertex in object coordinate system
- * eye - vertex in eye coordinate system
- * normal - normal vector in eye coordinate system
- * Output: texcoord - the resuling texture coordinate, if TexGen enabled.
- */
- void gl_do_texgen( const GLfloat obj[4],
- const GLfloat eye[4],
- const GLfloat normal[3],
- GLfloat texcoord[4] )
- {
- GLfloat u[3], two_nn, m, fx, fy, fz;
-
- if (CC.Texture.TexGenEnabled & S_BIT) {
- switch( CC.Texture.GenModeS) {
- case GL_OBJECT_LINEAR:
- texcoord[0] = DOT4( obj, CC.Texture.ObjectPlaneS );
- break;
- case GL_EYE_LINEAR:
- texcoord[0] = DOT4( eye, CC.Texture.EyePlaneS );
- break;
- case GL_SPHERE_MAP:
- COPY_3V( u, eye );
- NORMALIZE_3V( u );
- two_nn = 2.0*DOT3(normal,normal);
- fx = u[0] - two_nn * u[0];
- fy = u[1] - two_nn * u[1];
- fz = u[2] - two_nn * u[2];
- m = 2.0 * sqrt( fx*fx + fy*fy + (fz+1.0)*(fz+1.0) );
- if (m==0.0) {
- texcoord[0] = 0.0;
- }
- else {
- texcoord[0] = fx / m + 0.5;
- }
- break;
- }
- }
-
- if (CC.Texture.TexGenEnabled & T_BIT) {
- switch( CC.Texture.GenModeT) {
- case GL_OBJECT_LINEAR:
- texcoord[1] = DOT4( obj, CC.Texture.ObjectPlaneT );
- break;
- case GL_EYE_LINEAR:
- texcoord[1] = DOT4( eye, CC.Texture.EyePlaneT );
- break;
- case GL_SPHERE_MAP:
- /* TODO: safe to assume that m and fy valid from above??? */
- if (m==0.0) {
- texcoord[1] = 0.0;
- }
- else {
- texcoord[1] = fy / m + 0.5;
- }
- break;
- }
- }
-
- if (CC.Texture.TexGenEnabled & R_BIT) {
- switch( CC.Texture.GenModeR) {
- case GL_OBJECT_LINEAR:
- texcoord[2] = DOT4( obj, CC.Texture.ObjectPlaneR );
- break;
- case GL_EYE_LINEAR:
- texcoord[2] = DOT4( eye, CC.Texture.EyePlaneR );
- break;
- }
- }
-
- if (CC.Texture.TexGenEnabled & Q_BIT) {
- switch( CC.Texture.GenModeQ) {
- case GL_OBJECT_LINEAR:
- texcoord[3] = DOT4( obj, CC.Texture.ObjectPlaneQ );
- break;
- case GL_EYE_LINEAR:
- texcoord[3] = DOT4( eye, CC.Texture.EyePlaneQ );
- break;
- }
- }
- }
-
-
-
- /**********************************************************************/
- /* Texture Image */
- /**********************************************************************/
-
-
- /*
- * Convert the texture image given to glTexImage1D or glTexImage2D into
- * an array of GLubytes.
- * Return: address of texture image or NULL if error.
- */
- static GLubyte *unpack_texture( GLint components, GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid *pixels )
- {
- GLboolean rflag, gflag, bflag, aflag, lflag;
- GLuint elements;
- GLuint i, row;
- GLubyte *texture, *texptr;
- GLboolean scale_or_bias;
-
- scale_or_bias = CC.Pixel.RedScale !=1.0F || CC.Pixel.RedBias !=0.0F
- || CC.Pixel.GreenScale!=1.0F || CC.Pixel.GreenBias!=0.0F
- || CC.Pixel.BlueScale !=1.0F || CC.Pixel.BlueBias !=0.0F
- || CC.Pixel.AlphaScale!=1.0F || CC.Pixel.AlphaBias!=0.0F;
-
- switch (format) {
- case GL_COLOR_INDEX:
- elements = 1;
- rflag = gflag = bflag = aflag = lflag = GL_FALSE;
- break;
- case GL_RED:
- elements = 1;
- rflag = GL_TRUE;
- gflag = bflag = aflag = lflag = GL_FALSE;
- break;
- case GL_GREEN:
- elements = 1;
- gflag = GL_TRUE;
- rflag = bflag = aflag = lflag = GL_FALSE;
- break;
- case GL_BLUE:
- elements = 1;
- bflag = GL_TRUE;
- rflag = gflag = aflag = lflag = GL_FALSE;
- break;
- case GL_ALPHA:
- elements = 1;
- aflag = GL_TRUE;
- rflag = gflag = bflag = lflag = GL_FALSE;
- break;
- case GL_RGB:
- elements = 3;
- rflag = gflag = bflag = GL_TRUE;
- aflag = lflag = GL_FALSE;
- break;
- case GL_RGBA:
- elements = 4;
- rflag = gflag = bflag = aflag = GL_TRUE;
- lflag = GL_FALSE;
- break;
- case GL_LUMINANCE:
- elements = 1;
- rflag = gflag = bflag = aflag = GL_FALSE;
- lflag = GL_TRUE;
- break;
- case GL_LUMINANCE_ALPHA:
- elements = 2;
- lflag = aflag = GL_TRUE;
- rflag = gflag = bflag = GL_FALSE;
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glTexImage1/2D(format)" );
- return NULL;
- }
-
- /* Allocate texture memory */
- texture = (GLubyte *) malloc( width * height * components );
- if (!texture) {
- gl_error( GL_OUT_OF_MEMORY, "glTexImage1/2D" );
- return NULL;
- }
- texptr = texture;
-
- /* TODO: obey glPixelStore parameters! */
-
- /* Build texture map image row by row */
- for (row=0;row<height;row++) {
- if (type==GL_UNSIGNED_BYTE && format==GL_RGB && components==3
- && !scale_or_bias) {
- /*
- * A frequent and simple case
- */
- GLubyte *src = (GLubyte *) pixels + row * width * 3;
- MEMCPY( texptr, src, 3*width );
- texptr += 3*width;
- }
- else if (type==GL_UNSIGNED_BYTE && format==GL_RGBA && components==4
- && !scale_or_bias) {
- /*
- * Another frequent and simple case
- */
- GLubyte *src = (GLubyte *) pixels + row * width * 4;
- MEMCPY( texptr, src, 4*width );
- texptr += 4*width;
- }
- else {
- /*
- * General solution
- */
- GLfloat red[MAX_TEXTURE_SIZE], green[MAX_TEXTURE_SIZE];
- GLfloat blue[MAX_TEXTURE_SIZE], alpha[MAX_TEXTURE_SIZE];
-
- switch (type) {
- case GL_UNSIGNED_BYTE:
- {
- GLubyte *src = (GLubyte *) pixels + row * width * elements;
- for (i=0;i<width;i++) {
- if (lflag) {
- red[i] = green[i] = blue[i] = UBYTE_TO_FLOAT(*src++);
- }
- else {
- red[i] = rflag ? UBYTE_TO_FLOAT(*src++) : 0.0F;
- green[i] = gflag ? UBYTE_TO_FLOAT(*src++) : 0.0F;
- blue[i] = bflag ? UBYTE_TO_FLOAT(*src++) : 0.0F;
- }
- alpha[i] = aflag ? UBYTE_TO_FLOAT(*src++) : 1.0F;
- }
- }
- break;
- case GL_BYTE:
- {
- GLbyte *src = (GLbyte *) pixels + row * width * elements;
- for (i=0;i<width;i++) {
- if (lflag) {
- red[i] = green[i] = blue[i] = BYTE_TO_FLOAT(*src++);
- }
- else {
- red[i] = rflag ? BYTE_TO_FLOAT(*src++) : 0.0F;
- green[i] = gflag ? BYTE_TO_FLOAT(*src++) : 0.0F;
- blue[i] = bflag ? BYTE_TO_FLOAT(*src++) : 0.0F;
- }
- alpha[i] = aflag ? BYTE_TO_FLOAT(*src++) : 1.0F;
- }
- }
- break;
- case GL_UNSIGNED_SHORT:
- {
- GLushort *src = (GLushort *) pixels + row * width * elements;
- for (i=0;i<width;i++) {
- if (lflag) {
- red[i] = green[i] = blue[i] = USHORT_TO_FLOAT(*src++);
- }
- else {
- red[i] = rflag ? USHORT_TO_FLOAT(*src++) : 0.0F;
- green[i] = gflag ? USHORT_TO_FLOAT(*src++) : 0.0F;
- blue[i] = bflag ? USHORT_TO_FLOAT(*src++) : 0.0F;
- }
- alpha[i] = aflag ? USHORT_TO_FLOAT(*src++) : 1.0F;
- }
- }
- break;
- case GL_SHORT:
- {
- GLshort *src = (GLshort *) pixels + row * width * elements;
- for (i=0;i<width;i++) {
- if (lflag) {
- red[i] = green[i] = blue[i] = SHORT_TO_FLOAT(*src++);
- }
- else {
- red[i] = rflag ? SHORT_TO_FLOAT(*src++) : 0.0F;
- green[i] = gflag ? SHORT_TO_FLOAT(*src++) : 0.0F;
- blue[i] = bflag ? SHORT_TO_FLOAT(*src++) : 0.0F;
- }
- alpha[i] = aflag ? SHORT_TO_FLOAT(*src++) : 1.0F;
- }
- }
- break;
- /*TODO: implement rest of data types */
- case GL_FLOAT:
- {
- GLfloat *src = (GLfloat *) pixels + row * width * elements;
- for (i=0;i<width;i++) {
- if (lflag) {
- red[i] = green[i] = blue[i] = *src++;
- }
- else {
- red[i] = rflag ? *src++ : 0.0F;
- green[i] = gflag ? *src++ : 0.0F;
- blue[i] = bflag ? *src++ : 0.0F;
- }
- alpha[i] = aflag ? *src++ : 1.0F;
- }
- }
- break;
- default:
- gl_error( GL_INVALID_ENUM, "glTexImage1/2D(type)" );
- } /* switch */
-
- /* apply scale and/or bias */
- if (scale_or_bias) {
- for (i=0;i<width;i++) {
- register GLfloat r, g, b, a;
- r = red[i] * CC.Pixel.RedScale + CC.Pixel.RedBias;
- g = green[i] * CC.Pixel.GreenScale + CC.Pixel.GreenBias;
- b = blue[i] * CC.Pixel.BlueScale + CC.Pixel.BlueBias;
- a = alpha[i] * CC.Pixel.AlphaScale + CC.Pixel.AlphaBias;
- red[i] = CLAMP( r, 0.0F, 1.0F );
- green[i] = CLAMP( g, 0.0F, 1.0F );
- blue[i] = CLAMP( b, 0.0F, 1.0F );
- alpha[i] = CLAMP( a, 0.0F, 1.0F );
- }
- }
-
- /* save 8-bit components */
- switch (components) {
- case 1: /* red */
- for (i=0;i<width;i++) {
- *texptr++ = (GLubyte) (GLint) (red[i] * 255.0F);
- }
- break;
- case 2: /* red, alpha */
- for (i=0;i<width;i++) {
- *texptr++ = (GLubyte) (GLint) (red[i] * 255.0F);
- *texptr++ = (GLubyte) (GLint) (alpha[i] * 255.0F);
- }
- break;
- case 3: /* red, green, blue */
- for (i=0;i<width;i++) {
- *texptr++ = (GLubyte) (GLint) (red[i] * 255.0F);
- *texptr++ = (GLubyte) (GLint) (green[i] * 255.0F);
- *texptr++ = (GLubyte) (GLint) (blue[i] * 255.0F);
- }
- break;
- case 4: /* red, green, blue, alpha */
- for (i=0;i<width;i++) {
- *texptr++ = (GLubyte) (GLint) (red[i] * 255.0F);
- *texptr++ = (GLubyte) (GLint) (green[i] * 255.0F);
- *texptr++ = (GLubyte) (GLint) (blue[i] * 255.0F);
- *texptr++ = (GLubyte) (GLint) (alpha[i] * 255.0F);
- }
- break;
- } /* switch components */
-
- } /* general solution */
-
- } /* for row */
-
- return texture;
- }
-
-
- void gl_teximage1d( GLint level, GLint components,
- GLsizei width, GLint border,
- const GLubyte *pixels )
- {
- /* check if we can delete the current image */
- if (CC.TextureImage1D[level] && CC.TextureImage1DDeleteFlag[level]) {
- free( CC.TextureImage1D[level] );
- }
-
- CC.TextureComponents1D[level] = components;
- CC.TextureWidth1D[level] = width + border;
- CC.TextureBorder1D[level] = border;
- CC.TextureImage1D[level] = (GLubyte *) pixels;
- }
-
-
-
- void glTexImage1D( GLenum target, GLint level, GLint components,
- GLsizei width, GLint border, GLenum format,
- GLenum type, const GLvoid *pixels )
- {
- GLubyte *texture;
-
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glTexImage1D" );
- return;
- }
- if (target!=GL_TEXTURE_1D) {
- gl_error( GL_INVALID_ENUM, "glTexImage1D" );
- return;
- }
- if (level<0 || level>=MAX_TEXTURE_LEVELS) {
- gl_error( GL_INVALID_VALUE, "glTexImage1D(level)" );
- return;
- }
- if (components<0 || components>4) {
- gl_error( GL_INVALID_VALUE, "glTexImage1D(components)" );
- return;
- }
- if (width<0 || width>2+MAX_TEXTURE_SIZE) {
- gl_error( GL_INVALID_VALUE, "glTexImage1D(width)" );
- return;
- }
- /* assert( width == 2^k + 2*border for some k);*/
- if (border!=0 && border!=1) {
- gl_error( GL_INVALID_VALUE, "glTexImage1D(border)" );
- return;
- }
-
- /* Convert texture image to GLubytes */
- texture = unpack_texture( components, width+border, 1,
- format, type, pixels );
- if (!texture) {
- return;
- }
-
- /* install the texture */
- if (CC.ExecuteFlag) {
- gl_teximage1d( level, components, width, border, texture );
- }
- if (CC.CompileFlag) {
- gl_save_teximage1d( level, components, width, border, texture );
- /* Mark the image as don't delete, it'll get deleted if/when the */
- /* display list is deallocated. */
- CC.TextureImage1DDeleteFlag[level] = GL_FALSE;
- }
- else {
- /* Mark this image as deletable because it's not in a display list. */
- CC.TextureImage1DDeleteFlag[level] = GL_TRUE;
- }
- }
-
-
-
- void gl_teximage2d( GLint level, GLint components,
- GLsizei width, GLsizei height, GLint border,
- const GLubyte *pixels )
- {
- /* check if we can delete the current image */
- if (CC.TextureImage2D[level] && CC.TextureImage2DDeleteFlag[level]) {
- free( CC.TextureImage2D[level] );
- }
-
- CC.TextureComponents2D[level] = components;
- CC.TextureWidth2D[level] = width + border;
- CC.TextureHeight2D[level] = height + border;
- CC.TextureBorder2D[level] = border;
- CC.TextureImage2D[level] = (GLubyte *) pixels;
- }
-
-
-
- void glTexImage2D( GLenum target, GLint level, GLint components,
- GLsizei width, GLsizei height, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels )
- {
- GLubyte *texture;
-
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glTexImage2D" );
- return;
- }
- if (target!=GL_TEXTURE_2D) {
- gl_error( GL_INVALID_ENUM, "glTexImage2D(target)" );
- return;
- }
- if (level<0 || level>=MAX_TEXTURE_LEVELS) {
- gl_error( GL_INVALID_VALUE, "glTexImage2D(level)" );
- return;
- }
- if (components<0 || components>4) {
- gl_error( GL_INVALID_VALUE, "glTexImage2D(components)" );
- return;
- }
- if (width<0 || width>2+MAX_TEXTURE_SIZE) {
- gl_error( GL_INVALID_VALUE, "glTexImage2D(width)" );
- return;
- }
- if (height<0 || height>2+MAX_TEXTURE_SIZE) {
- gl_error( GL_INVALID_VALUE, "glTexImage2D(height)" );
- return;
- }
- /* assert( width == 2^k + 2*border for some k);*/
- if (border!=0 && border!=1) {
- gl_error( GL_INVALID_VALUE, "glTexImage2D(border)" );
- return;
- }
-
- /* Convert texture image to GLubytes */
- texture = unpack_texture( components, width+border, height+border,
- format, type, pixels );
- if (!texture) {
- return;
- }
-
- /* install the texture */
- if (CC.ExecuteFlag) {
- gl_teximage2d( level, components, width, height, border, texture );
- }
- if (CC.CompileFlag) {
- gl_save_teximage2d( level, components, width, height, border, texture );
- /* Mark the image as don't delete, it'll get deleted if/when the */
- /* display list is deallocated. */
- CC.TextureImage2DDeleteFlag[level] = GL_FALSE;
- }
- else {
- /* Mark this image as deletable because it's not in a display list. */
- CC.TextureImage2DDeleteFlag[level] = GL_TRUE;
- }
- }
-
-
-
- void glGetTexImage( GLenum target, GLint level, GLenum format,
- GLenum type, GLvoid *pixels )
- {
- /* TODO */
- }
-
-
-
-
- /**********************************************************************/
- /* Perform Texture Mapping */
- /**********************************************************************/
-
-
-
- /*
- * Combine incoming fragment color with texel color to produce output color.
- */
- static void apply_texture( GLuint n, GLint components,
- GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[],
- GLubyte tred[], GLubyte tgreen[], GLubyte tblue[], GLubyte talpha[] )
- {
- register GLuint i;
- GLint envred, envgreen, envblue;
-
- /* Texture environment color */
- envred = (GLint) (CC.Texture.EnvColor[0] * 255.0F);
- envgreen = (GLint) (CC.Texture.EnvColor[1] * 255.0F);
- envblue = (GLint) (CC.Texture.EnvColor[2] * 255.0F);
-
- if (CC.RedScale!=255.0) {
- /* This is a hack! Rescale input colors from [0,scale] to [0,255]. */
- GLfloat rscale = 255.0 / CC.RedScale;
- GLfloat gscale = 255.0 / CC.GreenScale;
- GLfloat bscale = 255.0 / CC.BlueScale;
- GLfloat ascale = 255.0 / CC.AlphaScale;
- for (i=0;i<n;i++) {
- red[i] = (GLint) (red[i] * rscale);
- green[i] = (GLint) (green[i] * gscale);
- blue[i] = (GLint) (blue[i] * bscale);
- alpha[i] = (GLint) (alpha[i] * ascale);
- }
- }
-
- /*
- * Use (A*(B+1)) >> 8 as a fast approximation of (A*B)/255 for A and B in [0,255]
- */
- #define PROD(A,B) (((GLint)(A) * (GLint)(B)+1) >> 8)
-
- switch (CC.Texture.EnvMode) {
- case GL_MODULATE:
- switch (components) {
- case 1: /* luminance */
- for (i=0;i<n;i++) {
- /* Cv = LtCf */
- red[i] = PROD( tred[i], red[i] );
- green[i] = PROD( tred[i], green[i] );
- blue[i] = PROD( tred[i], blue[i] );
- /* Av = Af */
- }
- break;
- case 2: /* luminance, alpha */
- for (i=0;i<n;i++) {
- /* Cv = LtCf */
- red[i] = PROD( tred[i], red[i] );
- green[i] = PROD( tred[i], green[i] );
- blue[i] = PROD( tred[i], blue[i] );
- /* Av = AtAf */
- alpha[i] = PROD( talpha[i], alpha[i] );
- }
- break;
- case 3: /* rgb */
- for (i=0;i<n;i++) {
- /* Cv = CtCf */
- red[i] = PROD( tred[i], red[i] );
- green[i] = PROD( tgreen[i], green[i] );
- blue[i] = PROD( tblue[i], blue[i] );
- /* Av = Af */
- }
- break;
- case 4: /* rgb, alpha */
- for (i=0;i<n;i++) {
- /* Cv = CtCf */
- red[i] = PROD( tred[i], red[i] );
- green[i] = PROD( tgreen[i], green[i] );
- blue[i] = PROD( tblue[i], blue[i] );
- /* Av = AtAf */
- alpha[i] = PROD( talpha[i], alpha[i] );
- }
- break;
- } /* components */
- break;
- case GL_DECAL:
- switch (components) {
- case 3:
- for (i=0;i<n;i++) {
- /* Cv = Ct */
- red[i] = tred[i];
- green[i] = tgreen[i];
- blue[i] = tblue[i];
- /* Av = Af */
- }
- break;
- case 4:
- for (i=0;i<n;i++) {
- /* Cv = (1-At)Cf + AtCt */
- GLint t = talpha[i], s = 255 - t;
- red[i] = PROD(s,red[i]) + PROD(t,tred[i]);
- green[i] = PROD(s,green[i]) + PROD(t,tgreen[i]);
- blue[i] = PROD(s,blue[i]) + PROD(t,tblue[i]);
- /* Av = Af */
- }
- break;
- }
- break;
- case GL_BLEND:
- switch (components) {
- case 1:
- for (i=0;i<n;i++) {
- /* Cv = (1-Lt)Cf + LtCc */
- GLint t = tred[i], s = 255 - t;
- red[i] = PROD(s,red[i]) + PROD(t,envred);
- green[i] = PROD(s,green[i]) + PROD(t,envgreen);
- blue[i] = PROD(s,blue[i]) + PROD(t,envblue);
- /* Av = Af */
- }
- break;
- case 2:
- for (i=0;i<n;i++) {
- /* Cv = (1-Lt)Cf + LtCc */
- GLint t = tred[i], s = 255 - t;
- red[i] = PROD(s,red[i]) + PROD(t,envred);
- green[i] = PROD(s,green[i]) + PROD(t,envgreen);
- blue[i] = PROD(s,blue[i]) + PROD(t,envblue);
- /* Av = AtAf */
- alpha[i] = PROD(talpha[i], alpha[i]);
- }
- break;
- case 3:
- for (i=0;i<n;i++) {
- /* Cv = (1-Ct)Cf + CtCc */
- red[i] = PROD((255-tred[i]), red[i] ) + PROD(tred[i], envred );
- green[i] = PROD((255-tgreen[i]),green[i]) + PROD(tgreen[i],envgreen);
- blue[i] = PROD((255-tblue[i]), blue[i] ) + PROD(tblue[i], envblue );
- /* Av = Af */
- }
- break;
- case 4:
- for (i=0;i<n;i++) {
- /* Cv = (1-Ct)Cf + CtCc */
- red[i] = PROD((255-tred[i]), red[i] ) + PROD(tred[i], envred );
- green[i] = PROD((255-tgreen[i]),green[i]) + PROD(tgreen[i],envgreen);
- blue[i] = PROD((255-tblue[i]), blue[i] ) + PROD(tblue[i], envblue );
- /* Av = AtAf */
- alpha[i] = PROD(talpha[i], alpha[i]);
- }
- break;
- }
- break;
- case GL_REPLACE_EXT:
- switch (components) {
- case 1:
- for (i=0;i<n;i++) {
- /* Cv = Lt */
- red[i] = green[i] = blue[i] = tred[i];
- /* Av = Af */
- }
- break;
- case 2:
- for (i=0;i<n;i++) {
- /* Cv = Lt */
- red[i] = green[i] = blue[i] = tred[i];
- /* Av = At */
- alpha[i] = talpha[i];
- }
- break;
- case 3:
- for (i=0;i<n;i++) {
- /* Cv = Ct */
- red[i] = tred[i];
- green[i] = tgreen[i];
- blue[i] = tblue[i];
- /* Av = Af */
- }
- break;
- case 4:
- for (i=0;i<n;i++) {
- /* Cv = Ct */
- red[i] = tred[i];
- green[i] = tgreen[i];
- blue[i] = tblue[i];
- /* Av = At */
- alpha[i] = talpha[i];
- }
- break;
- }
- break;
- }
- #undef PROD
-
- if (CC.RedScale!=255.0) {
- /* This is a hack! Rescale input colors from [0,255] to [0,scale]. */
- GLfloat rscale = CC.RedScale / 255.0;
- GLfloat gscale = CC.GreenScale / 255.0;
- GLfloat bscale = CC.BlueScale / 255.0;
- GLfloat ascale = CC.AlphaScale / 255.0;
- for (i=0;i<n;i++) {
- red[i] = (GLint) (red[i] * rscale);
- green[i] = (GLint) (green[i] * gscale);
- blue[i] = (GLint) (blue[i] * bscale);
- alpha[i] = (GLint) (alpha[i] * ascale);
- }
- }
-
-
- }
-
-
- /*
- * Apply the 1-D texture to an array of pixels.
- */
- void gl_texture_pixels_1d( GLuint n, GLfloat s[],
- GLubyte red[], GLubyte green[],
- GLubyte blue[], GLubyte alpha[] )
- {
- GLubyte tred[PB_SIZE], tgreen[PB_SIZE];
- GLubyte tblue[PB_SIZE], talpha[PB_SIZE];
- GLint alpha_offset;
- GLuint level;
- GLuint i;
-
- level = 0;
-
- if (!CC.TextureImage1D[level]) {
- /* no texture image */
- return;
- }
-
- /* alpha_offset = offset of the alpha value in the texel of a texture image */
- if (CC.TextureComponents1D[level]==2) {
- alpha_offset = 1;
- }
- else if (CC.TextureComponents1D[level]==4) {
- alpha_offset = 3;
- }
- else {
- alpha_offset = 0;
- }
-
- /*
- * Compute texel colors.
- */
- for (i=0;i<n;i++) {
- GLfloat ss;
- GLboolean border;
-
- border = GL_FALSE; /* Use border pixel color? */
-
- /* S COORDINATE */
- if (CC.Texture.WrapS1D==GL_REPEAT) {
- ss = s[i];
- while (ss<0.0F) ss += 1.0F;
- while (ss>1.0F) ss -= 1.0F;
- /* ss = s[i] - (GLfloat) (GLint) s[i];*/
- }
- else {
- /* GL_CLAMP */
- if (s[i]<0.0F || s[i]>1.0F) {
- if (CC.TextureBorder1D[level]) {
- /* use border texel */
- border = GL_TRUE;
- }
- else {
- /* use border color */
- ss = (s[i]<0.0F) ? 0.0F : 1.0F;
- }
- }
- else {
- ss = s[i];
- }
- }
-
- if (border) {
- tred[i] = (GLint) (CC.Texture.BorderColor[0] * 255.0F);
- tgreen[i] = (GLint) (CC.Texture.BorderColor[1] * 255.0F);
- tblue[i] = (GLint) (CC.Texture.BorderColor[2] * 255.0F);
- talpha[i] = (GLint) (CC.Texture.BorderColor[3] * 255.0F);
- }
- else {
- GLuint x, p;
- if (ss<1.0F) {
- x = (GLuint) (CC.TextureWidth1D[level] * ss);
- }
- else {
- x = CC.TextureWidth1D[level]-1;
- }
-
- p = CC.TextureComponents1D[level] * x;
- tred[i] = CC.TextureImage1D[level][p];
- tgreen[i] = CC.TextureImage1D[level][p+1];
- tblue[i] = CC.TextureImage1D[level][p+2];
- talpha[i] = CC.TextureImage1D[level][p+alpha_offset];
- }
- }
-
- apply_texture( n, CC.TextureComponents1D[level],
- red, green, blue, alpha, tred, tgreen, tblue, talpha );
- }
-
-
-
- /*
- * Apply the 2-D texture to an array of pixels.
- */
- void gl_texture_pixels_2d( GLuint n,
- GLfloat s[], GLfloat t[],
- GLubyte red[], GLubyte green[],
- GLubyte blue[], GLubyte alpha[] )
- {
- GLubyte tred[PB_SIZE], tgreen[PB_SIZE];
- GLubyte tblue[PB_SIZE], talpha[PB_SIZE];
- GLint alpha_offset;
- GLuint level;
- GLuint i;
-
- level = 0;
-
- if (!CC.TextureImage2D[level]) {
- /* no texture image */
- return;
- }
-
- /* alpha_offset = offset of the alpha value in the texel of a texture image */
- if (CC.TextureComponents2D[level]==2) {
- alpha_offset = 1;
- }
- else if (CC.TextureComponents2D[level]==4) {
- alpha_offset = 3;
- }
- else {
- alpha_offset = 0;
- }
-
- /*
- * Compute texel colors.
- */
- for (i=0;i<n;i++) {
- GLfloat ss, tt;
- GLboolean border;
-
- border = GL_FALSE; /* Use border pixel color? */
-
- /* S COORDINATE */
- if (CC.Texture.WrapS2D==GL_REPEAT) {
- ss = s[i];
- while (ss<0.0F) ss += 1.0F;
- while (ss>1.0F) ss -= 1.0F;
- /* ss = s[i] - (GLfloat) (GLint) s[i];*/
- }
- else {
- /* GL_CLAMP */
- if (s[i]<0.0F || s[i]>1.0F) {
- if (CC.TextureBorder2D[level]) {
- /* use border texel */
- border = GL_TRUE;
- }
- else {
- /* use border color */
- ss = (s[i]<0.0F) ? 0.0F : 1.0F;
- }
- }
- else {
- ss = s[i];
- }
- }
-
- /* T COORDINATE */
- if (CC.Texture.WrapT2D==GL_REPEAT) {
- tt = t[i];
- while (tt<0.0F) tt += 1.0F;
- while (tt>1.0F) tt -= 1.0F;
- /* tt = t[i] - (GLfloat) (GLint) t[i];*/
- }
- else {
- /* GL_CLAMP */
- if (t[i]<0.0F || t[i]>1.0F) {
- if (CC.TextureBorder2D[level]) {
- /* use border texel */
- border = GL_TRUE;
- }
- else {
- /* use border color */
- tt = (t[i]<0.0F) ? 0.0F : 1.0F;
- }
- }
- else {
- tt = t[i];
- }
- }
-
- if (border) {
- tred[i] = (GLint) (CC.Texture.BorderColor[0] * 255.0F);
- tgreen[i] = (GLint) (CC.Texture.BorderColor[1] * 255.0F);
- tblue[i] = (GLint) (CC.Texture.BorderColor[2] * 255.0F);
- talpha[i] = (GLint) (CC.Texture.BorderColor[3] * 255.0F);
- }
- else {
- GLuint x, y, p;
- if (ss<1.0F) {
- x = (GLuint) (CC.TextureWidth2D[level] * ss);
- }
- else {
- x = CC.TextureWidth2D[level]-1;
- }
- if (tt<1.0F) {
- y = (GLuint) (CC.TextureHeight2D[level] * tt);
- }
- else {
- y = CC.TextureHeight2D[level]-1;
- }
-
- p = CC.TextureComponents2D[level] * (CC.TextureWidth2D[level] * y + x);
- tred[i] = CC.TextureImage2D[level][p];
- tgreen[i] = CC.TextureImage2D[level][p+1];
- tblue[i] = CC.TextureImage2D[level][p+2];
- talpha[i] = CC.TextureImage2D[level][p+alpha_offset];
- }
- }
-
- apply_texture( n, CC.TextureComponents2D[level],
- red, green, blue, alpha, tred, tgreen, tblue, talpha );
- }
-
-